package com.css.zfzx.fxpg.modules.buildings.compute.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.css.bpm.platform.api.local.PlatformAPI;
import com.css.bpm.platform.org.division.repository.entity.DivisionEntity;
import com.css.bpm.platform.sys.dict.repository.entity.DictItemEntity;
import com.css.bpm.platform.utils.PlatformDateUtils;
import com.css.bpm.platform.utils.PlatformObjectUtils;
import com.css.bpm.platform.utils.PlatformSessionUtils;
import com.css.bpm.platform.utils.UUIDGenerator;
import com.css.zfzx.fxpg.modules.buildings.census.repository.*;
import com.css.zfzx.fxpg.modules.buildings.census.repository.entity.*;
import com.css.zfzx.fxpg.modules.buildings.census.viewobjects.FxHouseQueryParams;
import com.css.zfzx.fxpg.modules.buildings.compute.service.FxBuildingResistanceAbilityEvaluateService;
import com.css.zfzx.fxpg.modules.buildings.data.repository.FxBuildingsNativeRepository;
import com.css.zfzx.fxpg.modules.buildings.data.repository.entity.FxBuildingsEntity;
import com.css.zfzx.fxpg.modules.middle.repository.FxMiddleResultNativeRepository;
import com.css.zfzx.fxpg.modules.middle.repository.FxMiddleResultRepository;
import com.css.zfzx.fxpg.modules.middle.repository.entity.FxMiddleResultEntity;
import com.css.zfzx.fxpg.modules.middle.viewobjects.FxMiddleResultQueryParams;
import com.css.zfzx.fxpg.modules.vulnerability.province.repository.FxVulnerabilityProvinceNativeRepository;
import com.css.zfzx.fxpg.modules.vulnerability.province.repository.entity.FxVulnerabilityProvinceEntity;
import com.css.zfzx.fxpg.modules.vulnerability.province.viewobjects.FxVulnerabilityProvinceQueryParams;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author andy
 * @date 2020-11-11
 */
@Service
public class FxBuildingResistanceAbilityEvaluateServiceImpl implements FxBuildingResistanceAbilityEvaluateService {

    @Autowired
    private FxBuildingsNativeRepository fxBuildingsNativeRepository;

    @Autowired
    private FxVulnerabilityProvinceNativeRepository fxVulnerabilityProvinceNativeRepository;

    @Autowired
    private FxCityHouseNativeRepository fxCityHouseNativeRepository;
    @Autowired
    private FxCityNonHouseNativeRepository fxCityNonHouseNativeRepository;
    @Autowired
    private FxCountryDlHouseNativeRepository fxCountryDlHouseNativeRepository;
    @Autowired
    private FxCountryFzHouseNativeRepository fxCountryFzHouseNativeRepository;
    @Autowired
    private FxCountryJhHouseNativeRepository fxCountryJhHouseNativeRepository;
    @Autowired
    private FxCountryNonHouseNativeRepository fxCountryNonHouseNativeRepository;

    @Autowired
    private FxMiddleResultNativeRepository fxMiddleResultNativeRepository;
    @Autowired
    private FxMiddleResultRepository fxMiddleResultRepository;

    private Map<String, Map<String, Map<String, Map<String, Float>>>> fxVulnerabilityProvince = new HashMap<>();

    @Override
    public JSONObject buildingResistanceAbilityCompute(FxMiddleResultQueryParams queryParams, String userId) {
        JSONObject jsonObject = new JSONObject();

        String provinceName = getDivisionNameByCode("province", queryParams.getProvinceCode());
        String cityName = getDivisionNameByCode("city", queryParams.getCityCode());
        String areaName = getDivisionNameByCode("district", queryParams.getAreaCode());
        String districtName = provinceName + "-" + cityName + "-" + areaName;

        if (!fxVulnerabilityProvince.containsKey(districtName)) fxVulnerabilityProvince = initFxVulnerabilityProvince(queryParams, userId);

        FxHouseQueryParams fxHouseQueryParams = new FxHouseQueryParams();
        fxHouseQueryParams.setProvince(queryParams.getProvinceCode());
        fxHouseQueryParams.setCity(queryParams.getCityCode());
        fxHouseQueryParams.setArea(queryParams.getAreaCode());

        List<FxBuildingsEntity> fxBuildings = getFxAllHouses(fxHouseQueryParams, userId);

        String[] damageDegrees = null, intensities = null;
        String damageDegree = queryParams.getDamageDegree(), intensity = queryParams.getEarthquakeIntensity();
        if (PlatformObjectUtils.isEmpty(damageDegree)) {
            damageDegrees = new String[]{"0", "1", "2", "3", "4"};
        } else {
            damageDegrees = new String[]{damageDegree};
        }
        if (PlatformObjectUtils.isEmpty(intensity)) {
            intensities = new String[]{"6", "7", "8", "9", "10"};
        } else {
            intensities = new String[]{intensity};
        }
        for (int k = 0; k < intensities.length; k++) {
            for (int n = 0; n < damageDegrees.length; n++) {
                updateMiddleResult(fxBuildings, intensities[k], damageDegrees[n]);
            }
        }
        jsonObject.put("data", "success");
        return jsonObject;
    }
    private Map<String, Map<String, Map<String, Map<String, Float>>>> initFxVulnerabilityProvince(FxMiddleResultQueryParams queryParams, String userId) {
        /**
        {省-市-区县:
          {房屋结构类型: { 破坏程度 : {烈度: 易损性} }
          }
        Map<String, Map<String, Map<String, Map<String, Float>>>> fxVulnerabilityProvince = new HashMap<>();

          {房屋结构类型: {
              破坏程度 : {烈度: 易损性}
              }
          }
        Map<String, Map<String, Map<String, Float>>> type2map = new HashMap<>();

          {
              破坏程度 : {烈度: 易损性}
          }
        Map<String, Map<String, Float>> damageDegree2map = new HashMap<>();
        */
        String provinceName = getDivisionNameByCode("province", queryParams.getProvinceCode());
        String cityName = getDivisionNameByCode("city", queryParams.getCityCode());
        String areaName = getDivisionNameByCode("district", queryParams.getAreaCode());

        FxVulnerabilityProvinceQueryParams fxVulnerabilityProvinceQueryParams = new FxVulnerabilityProvinceQueryParams();
        fxVulnerabilityProvinceQueryParams.setProvince(provinceName);
        fxVulnerabilityProvinceQueryParams.setCity(cityName);
        fxVulnerabilityProvinceQueryParams.setArea(areaName);
        List<FxVulnerabilityProvinceEntity> fxVulnerabilityProvinceEntities = fxVulnerabilityProvinceNativeRepository.listFxVulnerabilityProvinces(fxVulnerabilityProvinceQueryParams);

        FxVulnerabilityProvinceEntity fxVulnerabilityProvinceEntity = null;
        String district = "", damageDegree = "", structureType = "";
        Float vVI = 0.0f, vVII = 0.0f, vVIII = 0.0f, vIX = 0.0f, vX = 0.0f;
        for (int i = 0; i < fxVulnerabilityProvinceEntities.size(); i++) {
            fxVulnerabilityProvinceEntity = fxVulnerabilityProvinceEntities.get(i);

            provinceName = fxVulnerabilityProvinceEntity.getProvince();
            cityName = fxVulnerabilityProvinceEntity.getCity();
            areaName = fxVulnerabilityProvinceEntity.getArea();

            structureType = fxVulnerabilityProvinceEntity.getStructureType();
            damageDegree = fxVulnerabilityProvinceEntity.getDamageDegree();

            vVI = fxVulnerabilityProvinceEntity.getVulnerabilityVI();
            vVII = fxVulnerabilityProvinceEntity.getVulnerabilityVII();
            vVIII = fxVulnerabilityProvinceEntity.getVulnerabilityVIII();
            vIX = fxVulnerabilityProvinceEntity.getVulnerabilityIX();
            vX = fxVulnerabilityProvinceEntity.getVulnerabilityX();

            district = provinceName + "-" + cityName + "-" + areaName;
            if (!fxVulnerabilityProvince.containsKey(district)) {
                Map<String, Map<String, Map<String, Float>>> type2map = new HashMap<>();
                Map<String, Map<String, Float>> damageDegree2map = new HashMap<>();
                Map<String, Float> intensity2vulnerability = new HashMap<>();
                intensity2vulnerability.put("6", vVI);
                intensity2vulnerability.put("7", vVII);
                intensity2vulnerability.put("8", vVIII);
                intensity2vulnerability.put("9", vIX);
                intensity2vulnerability.put("10", vX);
                damageDegree2map.put(damageDegree, intensity2vulnerability);
                type2map.put(structureType, damageDegree2map);
                fxVulnerabilityProvince.put(district, type2map);
            } else {
                Map<String, Map<String, Map<String, Float>>> type2map = fxVulnerabilityProvince.get(district);
                if (!type2map.containsKey(structureType)) {
                    Map<String, Map<String, Float>> damageDegree2map = new HashMap<>();
                    Map<String, Float> intensity2vulnerability = new HashMap<>();
                    intensity2vulnerability.put("6", vVI);
                    intensity2vulnerability.put("7", vVII);
                    intensity2vulnerability.put("8", vVIII);
                    intensity2vulnerability.put("9", vIX);
                    intensity2vulnerability.put("10", vX);
                    damageDegree2map.put(damageDegree, intensity2vulnerability);
                    type2map.put(structureType, damageDegree2map);
                } else {
                    Map<String, Map<String, Float>> damageDegree2map = type2map.get(structureType);
                    if (!damageDegree2map.containsKey(damageDegree)) {
                        Map<String, Float> intensity2vulnerability = new HashMap<>();
                        intensity2vulnerability.put("6", vVI);
                        intensity2vulnerability.put("7", vVII);
                        intensity2vulnerability.put("8", vVIII);
                        intensity2vulnerability.put("9", vIX);
                        intensity2vulnerability.put("10", vX);
                        damageDegree2map.put(damageDegree, intensity2vulnerability);
                    } else {
                        System.out.println(district + ", structureType: " + structureType + ", damageDegree: " + damageDegree + ", 出现冗余数据!");
                    }
                }
            }
        }
        return fxVulnerabilityProvince;
    }
    private List<FxBuildingsEntity> getFxAllHouses (FxHouseQueryParams fxHouseQueryParams, String userId) {

        List<FxBuildingsEntity> fxCityHouses = getFxCityHouses(fxHouseQueryParams, userId);
        /*List<FxBuildingsEntity> fxCityNonHouses = getFxCityNonHouses(fxHouseQueryParams, userId);
        List<FxBuildingsEntity> fxCountryDlHouses = getFxCountryDlHouses(fxHouseQueryParams, userId);
        List<FxBuildingsEntity> fxCountryJhHouses = getFxCountryJhHouses(fxHouseQueryParams, userId);
        List<FxBuildingsEntity> fxCountryNonHouses = getFxCountryNonHouses(fxHouseQueryParams, userId);*/

        //int total = fxCityHouses.size() + fxCityNonHouses.size() + fxCountryDlHouses.size() + fxCountryJhHouses.size() + fxCountryNonHouses.size();
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();
        fxBuildings.addAll(fxCityHouses);
        /*fxBuildings.addAll(fxCityNonHouses);
        fxBuildings.addAll(fxCountryDlHouses);
        fxBuildings.addAll(fxCountryJhHouses);
        fxBuildings.addAll(fxCountryNonHouses);*/

        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCityHouses (FxHouseQueryParams fxCityHouseQueryParams, String userId) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        String provinceCode = "", cityCode = "", areaCode = "", provinceName = "", cityName = "", areaName = "";
        List<FxCityHouseEntity> fxCityHouseEntities = fxCityHouseNativeRepository.listFxCityHouses(fxCityHouseQueryParams, userId);
        FxCityHouseEntity fxCityHouseEntity = null;
        for (int i = 0; i < fxCityHouseEntities.size(); i++) {
            fxCityHouseEntity = fxCityHouseEntities.get(i);

            String bh = fxCityHouseEntity.getBh();

            provinceCode = fxCityHouseEntity.getProvince();
            cityCode = fxCityHouseEntity.getCity();
            areaCode = fxCityHouseEntity.getDistrict();

            provinceName = getDivisionNameByCode("province", provinceCode);
            cityName = getDivisionNameByCode("city", cityCode);
            areaName = getDivisionNameByCode("district", areaCode);

            String dcmjStr = fxCityHouseEntity.getDcmj();
            Float dcmj = new Float(dcmjStr != null ? dcmjStr : "0.0");//建筑面积
            String czfwjglx = fxCityHouseEntity.getCzfwjglx();//结构类型
            if (czfwjglx == null) continue;

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setId(bh);
            fxBuildingsEntity.setProvince(provinceName);
            fxBuildingsEntity.setCity(cityName);
            fxBuildingsEntity.setArea(areaName);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }
        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCityNonHouses (FxHouseQueryParams fxCityHouseQueryParams, String userId) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        String provinceCode = "", cityCode = "", areaCode = "", provinceName = "", cityName = "", areaName = "";
        List<FxCityNonHouseEntity> fxCityHouseEntities = fxCityNonHouseNativeRepository.listFxCityNonHouses(fxCityHouseQueryParams, userId);
        FxCityNonHouseEntity fxCityNonHouseEntity = null;
        for (int i = 0; i < fxCityHouseEntities.size(); i++) {
            fxCityNonHouseEntity = fxCityHouseEntities.get(i);

            String bh = fxCityNonHouseEntity.getBh();

            provinceCode = fxCityNonHouseEntity.getProvince();
            cityCode = fxCityNonHouseEntity.getCity();
            areaCode = fxCityNonHouseEntity.getDistrict();

            provinceName = getDivisionNameByCode("province", provinceCode);
            cityName = getDivisionNameByCode("city", cityCode);
            areaName = getDivisionNameByCode("district", areaCode);

            String dcmjStr = fxCityNonHouseEntity.getDcmj();
            Float dcmj = new Float(dcmjStr != null ? dcmjStr : "0.0");//建筑面积
            String czfwjglx = fxCityNonHouseEntity.getCzfwjglx();//结构类型
            if (czfwjglx == null) continue;

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setId(bh);
            fxBuildingsEntity.setProvince(provinceName);
            fxBuildingsEntity.setCity(cityName);
            fxBuildingsEntity.setArea(areaName);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }
        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCountryDlHouses (FxHouseQueryParams fxCityHouseQueryParams, String userId) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        String provinceCode = "", cityCode = "", areaCode = "", provinceName = "", cityName = "", areaName = "";
        List<FxCountryDlHouseEntity> fxCountryDlHouseEntities = fxCountryDlHouseNativeRepository.listFxCountryDlHouses(fxCityHouseQueryParams, userId);
        FxCountryDlHouseEntity fxCountryDlHouseEntity = null;
        for (int i = 0; i < fxCountryDlHouseEntities.size(); i++) {
            fxCountryDlHouseEntity = fxCountryDlHouseEntities.get(i);

            String bh = fxCountryDlHouseEntity.getBh();

            provinceCode = fxCountryDlHouseEntity.getProvince();
            cityCode = fxCountryDlHouseEntity.getCity();
            areaCode = fxCountryDlHouseEntity.getDistrict();

            provinceName = getDivisionNameByCode("province", provinceCode);
            cityName = getDivisionNameByCode("city", cityCode);
            areaName = getDivisionNameByCode("district", areaCode);

            String dcmjStr = fxCountryDlHouseEntity.getDcmj();
            Float dcmj = new Float(dcmjStr != null ? dcmjStr : "0.0");//建筑面积
            String czfwjglx = fxCountryDlHouseEntity.getJglx();//结构类型
            if (czfwjglx == null) continue;

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setId(bh);
            fxBuildingsEntity.setProvince(provinceName);
            fxBuildingsEntity.setCity(cityName);
            fxBuildingsEntity.setArea(areaName);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }
        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCountryFzHouses (FxHouseQueryParams fxCityHouseQueryParams) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        /*String province = "", city = "", area = "";
        List<FxCountryFzHouseEntity> fxCountryDlHouseEntities = fxCountryFzHouseNativeRepository.listFxCountryFzHouses(fxCityHouseQueryParams);
        FxCountryFzHouseEntity fxCountryDlHouseEntity = null;
        for (int i = 0; i < fxCountryDlHouseEntities.size(); i++) {
            fxCountryDlHouseEntity = fxCountryDlHouseEntities.get(i);

            province = fxCountryDlHouseEntity.getProvince();
            city = fxCountryDlHouseEntity.getCity();
            area = fxCountryDlHouseEntity.getDistrict();

            Float dcmj = fxCountryDlHouseEntity.getDcmj();//建筑面积
            String czfwjglx = fxCountryDlHouseEntity.getCzfwjglx();//结构类型

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setProvince(province);
            fxBuildingsEntity.setCity(city);
            fxBuildingsEntity.setArea(area);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }*/
        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCountryJhHouses (FxHouseQueryParams fxCityHouseQueryParams, String userId) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        String provinceCode = "", cityCode = "", areaCode = "", provinceName = "", cityName = "", areaName = "";
        List<FxCountryJhHouseEntity> fxCountryJhHouseEntities = fxCountryJhHouseNativeRepository.listFxCountryJhHouses(fxCityHouseQueryParams, userId);
        FxCountryJhHouseEntity fxCountryJhHouseEntity = null;
        for (int i = 0; i < fxCountryJhHouseEntities.size(); i++) {
            fxCountryJhHouseEntity = fxCountryJhHouseEntities.get(i);

            String bh = fxCountryJhHouseEntity.getBh();

            provinceCode = fxCountryJhHouseEntity.getProvince();
            cityCode = fxCountryJhHouseEntity.getCity();
            areaCode = fxCountryJhHouseEntity.getDistrict();

            provinceName = getDivisionNameByCode("province", provinceCode);
            cityName = getDivisionNameByCode("city", cityCode);
            areaName = getDivisionNameByCode("district", areaCode);

            String dcmjStr = fxCountryJhHouseEntity.getDcmj();
            Float dcmj = new Float(dcmjStr != null ? dcmjStr : "0.0");//建筑面积
            String czfwjglx = fxCountryJhHouseEntity.getJglx();//结构类型
            if (czfwjglx == null) continue;

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setId(bh);
            fxBuildingsEntity.setProvince(provinceName);
            fxBuildingsEntity.setCity(cityName);
            fxBuildingsEntity.setArea(areaName);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }
        return fxBuildings;
    }
    private List<FxBuildingsEntity> getFxCountryNonHouses (FxHouseQueryParams fxCityHouseQueryParams, String userId) {
        List<FxBuildingsEntity> fxBuildings = new ArrayList<>();

        String provinceCode = "", cityCode = "", areaCode = "", provinceName = "", cityName = "", areaName = "";
        List<FxCountryNonHouseEntity> fxCountryNonHouseEntities = fxCountryNonHouseNativeRepository.listFxCountryNonHouses(fxCityHouseQueryParams, userId);
        FxCountryNonHouseEntity fxCountryNonHouseEntity = null;
        for (int i = 0; i < fxCountryNonHouseEntities.size(); i++) {
            fxCountryNonHouseEntity = fxCountryNonHouseEntities.get(i);

            String bh = fxCountryNonHouseEntity.getBh();

            provinceCode = fxCountryNonHouseEntity.getProvince();
            cityCode = fxCountryNonHouseEntity.getCity();
            areaCode = fxCountryNonHouseEntity.getDistrict();

            provinceName = getDivisionNameByCode("province", provinceCode);
            cityName = getDivisionNameByCode("city", cityCode);
            areaName = getDivisionNameByCode("district", areaCode);

            String dcmjStr = fxCountryNonHouseEntity.getDcmj();
            Float dcmj = new Float(dcmjStr != null ? dcmjStr : "0.0");//建筑面积
            String czfwjglx = fxCountryNonHouseEntity.getJglx();//结构类型
            if (czfwjglx == null) continue;

            FxBuildingsEntity fxBuildingsEntity = new FxBuildingsEntity();
            fxBuildingsEntity.setId(bh);
            fxBuildingsEntity.setProvince(provinceName);
            fxBuildingsEntity.setCity(cityName);
            fxBuildingsEntity.setArea(areaName);
            fxBuildingsEntity.setBuildingArea(dcmj);
            fxBuildingsEntity.setStructureType(czfwjglx);

            fxBuildings.add(fxBuildingsEntity);
        }
        return fxBuildings;
    }
    private void updateMiddleResult (List<FxBuildingsEntity> fxBuildings, String intensity, String damageDegree) {

        List<Map<String, Float>> result = getDistrict2WeightValue(fxBuildings, intensity, damageDegree);
        Map<String, Float> district2weightValue = result.get(0);
        Map<String, Float> district2totalArea = result.get(1);

        String provinceName = "", cityName = "", areaName = "", district = "", structureType = "";
        Float calculatedValue = 0.0f;
        String[] districtNames = null;
        for (Map.Entry<String, Float> entry : district2weightValue.entrySet()) {

            district = entry.getKey();
            districtNames = district.split("-");
            provinceName = districtNames[0];
            cityName = districtNames[1];
            areaName = districtNames[2];

            Float totalArea = district2totalArea.get(district);
            calculatedValue = entry.getValue() / totalArea;

            FxMiddleResultQueryParams fxMiddleResultQueryParams = new FxMiddleResultQueryParams();
            fxMiddleResultQueryParams.setProvince(provinceName);
            fxMiddleResultQueryParams.setCity(cityName);
            fxMiddleResultQueryParams.setArea(areaName);
            fxMiddleResultQueryParams.setEarthquakeIntensity(intensity);
            fxMiddleResultQueryParams.setDamageDegree(damageDegree);

            FxMiddleResultEntity fxMiddleResultEntity = null;
            List<FxMiddleResultEntity> fxMiddleResults = fxMiddleResultNativeRepository.listFxMiddleResultss(fxMiddleResultQueryParams);
            if (fxMiddleResults.size() == 1) {
                fxMiddleResultEntity = fxMiddleResults.get(0);
                fxMiddleResultEntity.setCalculatedValue(new Double(calculatedValue));
                fxMiddleResultEntity.setUpdateUser(PlatformSessionUtils.getUserId());
                fxMiddleResultEntity.setUpdateTime(PlatformDateUtils.getCurrentTimestamp());
            } else if (fxMiddleResults.size() == 0) {
                fxMiddleResultEntity = new FxMiddleResultEntity();
                String uuid = UUIDGenerator.getUUID();
                fxMiddleResultEntity.setId(uuid);
                fxMiddleResultEntity.setProvince(provinceName);
                fxMiddleResultEntity.setCity(cityName);
                fxMiddleResultEntity.setArea(areaName);
                fxMiddleResultEntity.setEarthquakeIntensity(intensity);
                fxMiddleResultEntity.setDamageDegree(damageDegree);
                fxMiddleResultEntity.setCalculatedValue(new Double(calculatedValue));
                fxMiddleResultEntity.setCorrectedValue(new Double(calculatedValue));
                fxMiddleResultEntity.setIsValid("1");
                fxMiddleResultEntity.setCreateUser(PlatformSessionUtils.getUserId());
                fxMiddleResultEntity.setCreateTime(PlatformDateUtils.getCurrentTimestamp());
            } else {
                System.out.println(provinceName + ", " + cityName + ", " + areaName + ", intensity: " + intensity + ", damageDegree: " + damageDegree + ", 存在冗余数据!");
            }
            this.fxMiddleResultRepository.save(fxMiddleResultEntity);
        }
    }
    private List<Map<String, Float>> getDistrict2WeightValue (List<FxBuildingsEntity> fxBuildings, String intensity, String damageDegree) {

        List<Map<String, Float>> result = new ArrayList<>(2);

        String provinceName = "", cityName = "", areaName = "", district = "", structureType = "";
        Map<String, Float> district2weightValue = new HashMap<>();
        Map<String, Float> district2totalArea = new HashMap<>();
        for (int i = 0; i < fxBuildings.size(); i++) {

            FxBuildingsEntity fxBuildingsEntity = fxBuildings.get(i);

            provinceName = fxBuildingsEntity.getProvince();
            cityName = fxBuildingsEntity.getCity();
            areaName = fxBuildingsEntity.getArea();

            district = provinceName + "-" + cityName + "-" + areaName;
            Map<String, Map<String, Map<String, Float>>> type2map = fxVulnerabilityProvince.get(district);

            structureType = fxBuildingsEntity.getStructureType();
            Map<String, Map<String, Float>> damageDegree2map = type2map.get(structureType);
            Map<String, Float> intensity2vulnerability = damageDegree2map.get(damageDegree);
            Float vulnerability = intensity2vulnerability.get(intensity);

            Float buildingArea = fxBuildingsEntity.getBuildingArea();

            if (district2weightValue.containsKey(district)) {
                district2weightValue.put(district, district2weightValue.get(district) + buildingArea * vulnerability);
            } else {
                district2weightValue.put(district, buildingArea * vulnerability);
            }

            if (district2totalArea.containsKey(district)) {
                district2totalArea.put(district, district2totalArea.get(district) + buildingArea);
            } else {
                district2totalArea.put(district, buildingArea);
            }
        }

        result.add(district2weightValue);
        result.add(district2totalArea);
        return result;
    }




    @Override
    public JSONObject buildingResistanceAbilityDistrict(FxMiddleResultQueryParams queryParams, String userId) {

        JSONObject jsonObject = new JSONObject();

        if (fxVulnerabilityProvince.size() == 0) fxVulnerabilityProvince = initFxVulnerabilityProvince(queryParams, userId);

        FxHouseQueryParams fxHouseQueryParams = new FxHouseQueryParams();
        fxHouseQueryParams.setProvince(queryParams.getProvince());
        fxHouseQueryParams.setCity(queryParams.getCity());
        fxHouseQueryParams.setArea(queryParams.getArea());

        List<FxBuildingsEntity> fxBuildings = getFxAllHouses(fxHouseQueryParams, userId);

        Map<String, Float> district2weightValue = new HashMap<>();
        Map<String, Float> district2totalArea = new HashMap<>();
        FxBuildingsEntity fxBuildingsEntity = null;
        String province = "", city = "", area = "", district = "", structureType = "", intensityType = queryParams.getEarthquakeIntensity();
        Float buildingArea = 0.0f;
        for (int i = 0; i < fxBuildings.size(); i++) {
            fxBuildingsEntity = fxBuildings.get(i);

            province = fxBuildingsEntity.getProvince();
            city = fxBuildingsEntity.getCity();
            area = fxBuildingsEntity.getArea();

            structureType = fxBuildingsEntity.getStructureType();
            buildingArea = fxBuildingsEntity.getBuildingArea();

            district = province + "-" + city + "-" + area;
            Map<String, Map<String, Map<String, Float>>> type2map = fxVulnerabilityProvince.get(district);
            Map<String, Map<String, Float>> damageDegree2map = type2map.get(structureType);
            Float vulnerability = getVulnerabilityValueForDistrict (intensityType, damageDegree2map);

            if (district2weightValue.containsKey(district)) {
                district2weightValue.put(district, district2weightValue.get(district) + vulnerability * buildingArea);
            } else {
                district2weightValue.put(district, vulnerability * buildingArea);
            }
            if (district2totalArea.containsKey(district)) {
                district2totalArea.put(district, district2totalArea.get(district) + buildingArea);
            } else {
                district2totalArea.put(district, buildingArea);
            }
        }

        Map<String, Float> result = new HashMap<>();
        Float calculatedValue = 0.0f;
        for (Map.Entry<String, Float> entry : district2weightValue.entrySet()) {
            district = entry.getKey();
            Float totalArea = district2totalArea.get(district);
            calculatedValue = entry.getValue() / totalArea;
            result.put(district, calculatedValue);
        }
        jsonObject.put("data", result);
        return jsonObject;
    }
    private Float getVulnerabilityValueForDistrict (String intensityType, Map<String, Map<String, Float>> damageDegree2map) {
        Float vulnerability = 0.0f;;
        String damageDegree = "";
        Map<String, Float> intensity2vulnerability = null;
        for (Map.Entry<String, Map<String, Float>> entry : damageDegree2map.entrySet()) {
            damageDegree = entry.getKey();
            intensity2vulnerability = entry.getValue();
            if ("3".equals(damageDegree) || "4".equals(damageDegree)) {
                if ("6".equals(intensityType)) {
                    vulnerability += intensity2vulnerability.get("6");
                } else if ("7".equals(intensityType)) {
                    vulnerability += intensity2vulnerability.get("7");
                } else if ("8".equals(intensityType)) {
                    vulnerability += intensity2vulnerability.get("8");
                } else if ("9".equals(intensityType)) {
                    vulnerability += intensity2vulnerability.get("9");
                } else if ("10".equals(intensityType)) {
                    vulnerability += intensity2vulnerability.get("10");
                }
            }
        }
        return vulnerability;
    }

    @Override
    public List<DictItemEntity> getValidDictItemsByDictCode(String dictCode) {
        List<DictItemEntity> validDictItems = PlatformAPI.getDictAPI().getValidDictItemsByDictCode(dictCode);
        return validDictItems;
    }


    private Map<String, Map<String, String>> divisionCodeToName = new HashMap<>();
    private String getDivisionNameByCode (String level, String code) {
        if (divisionCodeToName.size() == 0) divisionCodeToName = initDivisionNameByCode();
        return divisionCodeToName.get(level).get(code);
    }
    private Map<String, Map<String, String>> initDivisionNameByCode () {
        Map<String, Map<String, String>> divisionCodeToName = new HashMap<>();

        Map<String, String> provinceCodeToName = new HashMap<>();
        Map<String, String> cityCodeToName = new HashMap<>();
        Map<String, String> districtCodeToName = new HashMap<>();

        String divisionId = "", provinceCode = "", provinceName = "", cityCode = "", cityName = "", districtCode = "", districtName = "";
        DivisionEntity divisionEntity = null;
        List<DivisionEntity> divisionEntities_1 = PlatformAPI.getDivisionAPI().getSubDivisions("root");
        for (int i = 0; i < divisionEntities_1.size(); i++) {
            divisionEntity = divisionEntities_1.get(i);
            provinceCode = divisionEntity.getDivisionCode();
            provinceName = divisionEntity.getDivisionName();
            provinceCodeToName.put(provinceCode, provinceName);

            divisionId = divisionEntity.getDivisionId();
            List<DivisionEntity> divisionEntities_2 = PlatformAPI.getDivisionAPI().getSubDivisions(divisionId);
            for (int j = 0; j < divisionEntities_2.size(); j++) {
                divisionEntity = divisionEntities_2.get(j);
                cityCode = divisionEntity.getDivisionCode();
                cityName = divisionEntity.getDivisionName();
                cityCodeToName.put(cityCode, cityName);

                divisionId = divisionEntity.getDivisionId();
                List<DivisionEntity> divisionEntities_3 = PlatformAPI.getDivisionAPI().getSubDivisions(divisionId);
                for (int k = 0; k < divisionEntities_3.size(); k++) {
                    divisionEntity = divisionEntities_3.get(k);
                    districtCode = divisionEntity.getDivisionCode();
                    districtName = divisionEntity.getDivisionName();
                    districtCodeToName.put(districtCode, districtName);
                }
            }
        }
        divisionCodeToName.put("province", provinceCodeToName);
        divisionCodeToName.put("city", cityCodeToName);
        divisionCodeToName.put("district", districtCodeToName);
        return divisionCodeToName;
    }
}
